#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
时间调度模块 - Flask版本
"""

import threading
import time
import os
from datetime import datetime, timedelta
import json
from modules.database import db_manager
from modules.audio_player import audio_player

class BellScheduler:
    def __init__(self):
        """初始化调度器"""
        self.is_running = False
        self.schedule_thread = None
        self.bell_times = []  # 存储铃声时间点
        self.skipped_bell = None  # 存储被跳过的铃声时间点
        self.current_weekday_plan_id = None  # 当前星期几的方案ID
        self.load_schedule()
        self.status_callback = None  # 状态更新回调函数
    
    def set_status_callback(self, callback):
        """
        设置状态更新回调函数
        
        Args:
            callback (function): 回调函数
        """
        self.status_callback = callback
    
    def notify_status(self, message):
        """通知状态更新"""
        if hasattr(self, 'status_callback') and self.status_callback:
            self.status_callback(message)
    
    def set_weekday_plan(self, plan_id):
        """
        设置当前星期几的方案
        
        Args:
            plan_id (int): 方案ID
        """
        self.current_weekday_plan_id = plan_id
        self.load_schedule()
    
    def load_schedule(self):
        """从数据库加载方案"""
        try:
            # 获取当前星期几对应的方案ID
            weekdays = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']
            current_weekday = weekdays[datetime.now().weekday()]
            weekday_plan_id = db_manager.get_weekday_plan(current_weekday)
            
            # 如果设置了星期方案，则只加载该方案的铃声时间点
            if weekday_plan_id is not None:
                bell_times = db_manager.get_bell_times_by_plan(weekday_plan_id)
                # 转换为原始格式
                self.bell_times = [(bt['time'], bt['audio_file'], bt['volume'], "default") 
                                  for bt in bell_times]
            else:
                # 查询启用的方案中的铃声时间点
                active_plans = db_manager.get_active_plans()
                self.bell_times = []
                for plan in active_plans:
                    bell_times = db_manager.get_bell_times_by_plan(plan['id'])
                    for bt in bell_times:
                        self.bell_times.append((bt['time'], bt['audio_file'], bt['volume'], plan['type']))
            
            self.notify_status(f"已加载 {len(self.bell_times)} 个铃声时间点")
            return True
        except Exception as e:
            print(f"加载方案时出错: {e}")
            self.notify_status(f"加载方案时出错: {e}")
            return False
    
    def add_bell_time(self, bell_time, audio_file):
        """
        添加铃声时间点
        
        Args:
            bell_time (str): 铃声时间(HH:MM:SS格式)
            audio_file (str): 音频文件路径
        """
        # 使用固定的默认音量80
        self.bell_times.append((bell_time, audio_file, 80, "default"))
    
    def remove_bell_time(self, bell_time):
        """
        移除铃声时间点
        
        Args:
            bell_time (str): 铃声时间(HH:MM:SS格式)
        """
        self.bell_times = [bt for bt in self.bell_times if bt[0] != bell_time]
    
    def get_next_bell_time(self):
        """获取下一个铃声时间"""
        if not self.bell_times:
            return None
        
        now = datetime.now().time()
        for bell_time_str, audio_file, volume, plan_type in self.bell_times:
            bell_time = datetime.strptime(bell_time_str, "%H:%M:%S").time()
            if bell_time > now:
                # 如果这个铃声被跳过了，继续查找下一个
                if bell_time_str == self.skipped_bell:
                    continue
                # 返回时间、铃声文件信息
                return {
                    'time': bell_time_str,
                    'audio_file': audio_file,
                    'volume': 80,  # 固定音量
                    'plan_type': plan_type
                }
        # 如果今天没有更多铃声，返回明天第一个
        for bell_time_str, audio_file, volume, plan_type in self.bell_times:
            if bell_time_str != self.skipped_bell:
                return {
                    'time': bell_time_str,
                    'audio_file': audio_file,
                    'volume': 80,  # 固定音量
                    'plan_type': plan_type
                }
        return None
    
    def skip_next_bell(self):
        """跳过下次铃声"""
        next_bell = self.get_next_bell_time()
        if next_bell:
            self.skipped_bell = next_bell['time']  # 只存储时间字符串
            self.notify_status(f"已跳过下次铃声: {next_bell['time']}")
            return next_bell
        return None
    
    def clear_skipped_bell(self):
        """清除跳过的铃声标记"""
        self.skipped_bell = None
    
    def start_scheduler(self):
        """启动调度器"""
        if self.is_running:
            return
        
        self.is_running = True
        self.schedule_thread = threading.Thread(target=self._schedule_loop)
        self.schedule_thread.daemon = True
        self.schedule_thread.start()
        self.notify_status("铃声调度器已启动")
        print("铃声调度器已启动")
    
    def stop_scheduler(self):
        """停止调度器"""
        self.is_running = False
        if self.schedule_thread:
            self.schedule_thread.join()
        self.notify_status("铃声调度器已停止")
        print("铃声调度器已停止")
    
    def _schedule_loop(self):
        """调度循环"""
        last_weekday = datetime.now().weekday()  # 记录上一次的星期几
        
        while self.is_running:
            now = datetime.now()
            current_time_str = now.strftime("%H:%M:%S")
            
            # 检查是否到了新的一天（星期几变化）
            if now.weekday() != last_weekday:
                # 重新加载方案
                self.load_schedule()
                last_weekday = now.weekday()
            
            # 检查是否有铃声需要播放
            for bell_time_str, audio_file, _, _ in self.bell_times:
                # 如果这个铃声被跳过了，不播放
                if bell_time_str == self.skipped_bell:
                    continue
                if bell_time_str == current_time_str:
                    # 触发铃声播放事件，使用固定音量80
                    self._trigger_bell(audio_file, 80)
                    # 播放后清除跳过标记
                    self.clear_skipped_bell()
            
            # 每秒检查一次
            time.sleep(1)
    
    def _trigger_bell(self, audio_file, volume):
        """
        触发铃声播放
        
        Args:
            audio_file (str): 音频文件路径
            volume (int): 音量大小
        """
        message = f"触发铃声播放: {audio_file} (音量: {volume})"
        print(message)
        self.notify_status(message)
        
        # 播放音频文件
        # 构建完整的音频文件路径
        from config import AUDIO_DIR, BASE_DIR
        # 如果audio_file已经是完整路径，则直接使用，否则拼接路径
        if os.path.isabs(audio_file):
            full_audio_path = audio_file
        else:
            full_audio_path = os.path.join(BASE_DIR, audio_file)
            # 如果在BASE_DIR中找不到，尝试在AUDIO_DIR中查找
            if not os.path.exists(full_audio_path):
                full_audio_path = os.path.join(AUDIO_DIR, audio_file)
        audio_player.play_audio(full_audio_path, volume)

# 全局调度器实例
scheduler = BellScheduler()

def main():
    # 测试代码
    scheduler = BellScheduler()
    print("时间调度模块测试")
    
if __name__ == "__main__":
    main()